package com.boarsoft.boar.batch.biz;

import java.util.List;

import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.boarsoft.boar.batch.entity.BatchEvent;
import com.boarsoft.boar.batch.entity.BatchExecution;
import com.boarsoft.boar.batch.entity.BatchInfo;
import com.boarsoft.common.Util;
import com.boarsoft.common.dao.PagedResult;
import com.boarsoft.hibernate.biz.SimpleBizImpl;

@Component
public class BatchExecutionBizImpl extends SimpleBizImpl implements BatchExecutionBiz {
    /** */
    // private SequenceGeneratorClient sequence;

    /**
     * 插入一条新的任务组执行记录
     *
     * @return 主键
     */
    @Override
    @Transactional
    public String save(BatchExecution o) {
        /*if (Util.strIsEmpty(o.getId())) {
            //dao.save(o);
            return "id不允许为空";
        }*/
        dao.save(o);
        return o.getId();
    }

    /**
     * 更新执行记录
     *
     * @return 主键
     */
    @Override
    @Transactional
    public String update(BatchExecution o) {
        if (Util.strIsEmpty(o.getId())) {
            //dao.save(o);
            return "id不允许为空";
        }
        dao.update(o);
        return o.getId();
    }

    /**
     * 根据任务组ID获取最后的一次执行记录。目的是检查有无正在执行的记录。
     *
     * @param infoId
     * @return
     */
    @Override
    @Transactional(readOnly = true)
    public BatchExecution last(String infoId) {
        StringBuilder sb = new StringBuilder();
        sb.append("and infoId='").append(infoId);
        sb.append("' order by startTime desc");
        String wql = sb.toString();
        List<BatchExecution> lt = dao.list(BatchExecution.class, wql, 1, 1);
        if (lt.isEmpty()) {
            return null;
        }
        return lt.get(0);
    }

    @Override
    @Transactional(readOnly = true)
    public BatchExecution get(String id) {
        return dao.get(BatchExecution.class, id);
    }

    @Override
    @Transactional(readOnly = true)
    public BatchExecution getBybatchId(String batchId) {
        StringBuilder sb = new StringBuilder();
        sb.append(" and batchId = '").append(batchId).append("'");
        sb.append(" order by startTime desc");
        int total = dao.getTotal("select count(batchId) ".concat(" from ")
                .concat(BatchExecution.class.getName()).concat(" where 1=1 ").concat(sb.toString()));
        BatchExecution be = null;
        if(total <= 1){
            be = dao.find(BatchExecution.class, sb.toString());
        } else {
            List<BatchExecution> list = dao.list(BatchExecution.class, sb.toString());
            be = list.get(0);
        }
        return be;
    }

    @Override
    @Transactional(readOnly = true)
    public List<BatchExecution> getAllByBatchId(String batchId) {
        StringBuilder sb = new StringBuilder();
        sb.append(" and batchId = '").append(batchId).append("'");
        sb.append(" order by startTime desc");
        int total = dao.getTotal("select count(batchId) ".concat(" from ")
                .concat(BatchExecution.class.getName()).concat(" where 1=1 ").concat(sb.toString()));
        List<BatchExecution> list = dao.list(BatchExecution.class, sb.toString());
        return list;
    }

    @Override
    @Transactional(readOnly = true)
    public List<BatchExecution> getSonNods(String id) {
        String hql = " from BatchExecution where 1=1 and vParentId = '" + id + "'";
        List<BatchExecution> list = this.dao.list(hql, BatchExecution.class);
        return list;
    }

    @Override
    @Transactional(readOnly = true)
    public List<BatchExecution> list(String[] ids) {
        StringBuilder sb = new StringBuilder();
        sb.append(" and id in (");
        for (int i = 0; i < ids.length; i++) {
            if (i < ids.length - 1) {
                sb.append("'").append(ids[i]).append("',");
            } else {
                sb.append("'").append(ids[i]).append("'");
            }
        }
        sb.append(")");
        String wql = sb.toString();
        return dao.list(BatchExecution.class, wql);
    }

    @Override
    @Transactional(readOnly = true)
    public List<BatchExecution> list() {
        StringBuilder sb = new StringBuilder();
        sb.append(" and status in (").append(BatchExecution.STATUS_RUNNING);
        sb.append(", ").append(BatchExecution.STATUS_NEW);
        sb.append(", ").append(BatchExecution.STATUS_QUEUED);
        sb.append(", ").append(BatchExecution.STATUS_SUSPEND);
        sb.append(", ").append(BatchExecution.STATUS_STOPPING).append(")");
        String wql = sb.toString();
        return dao.list(BatchExecution.class, wql);
    }

    @Override
    @Transactional(readOnly = true)
    public List<BatchExecution> list(String id) {
        StringBuilder wql = new StringBuilder();
        wql.append(" and path like '%").append(id).append("%'");
        return dao.list(BatchExecution.class, wql.toString());
    }

    @Override
    @Transactional(readOnly = true)
    public List<BatchExecution> list(String startTime, String endTime) {
        StringBuilder wql = new StringBuilder();
        if (Util.strIsNotEmpty(startTime)) {
            wql.append(" and startTime >= '").append(startTime).append("'");
        }
        if (Util.strIsNotEmpty(endTime)) {
            wql.append(" and endTime <= '").append(endTime).append("'");
        }
        wql.append(" and parentId is null ");
        return dao.list(BatchExecution.class, wql.toString());
    }

    @Override
    @Transactional(readOnly = true)
    public PagedResult<BatchExecution> list(String startTime, String endTime, int pageNo, int pageSize) {
        StringBuilder wql = new StringBuilder();
        if (Util.strIsNotEmpty(startTime)) {
            wql.append(" and startTime >= '").append(startTime).append("'");
        }
        if (Util.strIsNotEmpty(endTime)) {
            wql.append(" and endTime <= '").append(endTime).append("'");
        }
        wql.append(" and parentId is null ");
        int total = dao.getTotal("select count(id) ".concat(" from ")
                .concat(BatchExecution.class.getName()).concat(" where 1=1 ").concat(wql.toString()));
        List<BatchExecution> lt = dao.list(" from ".concat(BatchExecution.class.getName())
                .concat("where 1=1 ").concat(wql.toString()), pageNo, pageSize);
        return new PagedResult<BatchExecution>(total, lt, pageNo, pageSize);
    }

    @Override
    @Transactional(readOnly = true)
    public PagedResult<BatchExecution> list(String catalog, String key, String startTime, String endTime, int pageNo, int pageSize) {
        StringBuilder sb = new StringBuilder();
        sb.append("from ").append(BatchExecution.class.getName());
        sb.append(" where catalog = '").append(catalog).append("'");
        if (Util.strIsNotEmpty(key)) {
            sb.append(" and (code like '%").append(key);
            sb.append("'% or name like '%").append(key).append("%')");
        }
        if (Util.strIsNotEmpty(startTime)) {
            sb.append(" and startTime >= '").append(startTime).append("'");
        }
        if (Util.strIsNotEmpty(endTime)) {
            sb.append(" and endTime <= '").append(endTime).append("'");
        }
        String hql = sb.toString();
        int total = dao.getTotal("select count(id) ".concat(hql));
        List<BatchExecution> lt = dao.list(hql, pageNo, pageSize);
        return new PagedResult<BatchExecution>(total, lt, pageNo, pageSize);
    }

    @Override
    @Transactional(readOnly = true)
    public PagedResult<BatchExecution> list(String infoId, String startTime, String endTime, int pageNo, int pageSize) {
        StringBuilder sb = new StringBuilder();
        sb.append(" and infoId = '").append(infoId).append("'");
        if (Util.strIsNotEmpty(startTime)) {
            sb.append(" and startTime >= '").append(startTime).append("'");
        }
        if (Util.strIsNotEmpty(endTime)) {
            sb.append(" and endTime <= '").append(endTime).append("'");
        }
        sb.append(" order by startTime desc");
        String hql = sb.toString();
        int total = dao.getTotal("select count(id) ".concat(" from ")
                .concat(BatchExecution.class.getName()).concat(" where 1=1 ").concat(hql));
        List<BatchExecution> lt = dao.list(" from ".concat(BatchExecution.class.getName())
                .concat(" where 1=1 ").concat(hql), pageNo, pageSize);
        return new PagedResult<BatchExecution>(total, lt, pageNo, pageSize);
    }

    @Override
    @Transactional(readOnly = true)
    public List<BatchExecution> list(short status) {
        StringBuilder sb = new StringBuilder("and status=").append(status);
        return dao.list(BatchExecution.class, sb.toString());
    }

    @Override
    @Transactional(readOnly = true)
    public PagedResult<Object[]> listExecuting(int pageNo, int pageSize) {
        StringBuilder sb = new StringBuilder();
        sb.append("from ").append(BatchExecution.class.getName()).append(" e, ");
        sb.append(BatchInfo.class.getName()).append(" i");
        sb.append(" where e.infoId = i.id and ");
        sb.append("e.status in (").append(BatchExecution.STATUS_NEW);
        sb.append(", ").append(BatchExecution.STATUS_QUEUED);
        sb.append(", ").append(BatchExecution.STATUS_RUNNING);
        sb.append(", ").append(BatchExecution.STATUS_STOPPING).append(")");
        sb.append(" order by e.infoId, e.startTime");
        String hql = sb.toString();
        int total = dao.getTotal("select count(e.id) ".concat(hql));
        List<Object[]> lt = dao.list(hql, pageNo, pageSize);
        return new PagedResult<Object[]>(total, lt, pageNo, pageSize);
    }

    @Override
    @Transactional
    public void delete(String id) {
        // 删除执行记录的相关事件
        StringBuilder sb = new StringBuilder();
        sb.append("delete from ").append(BatchEvent.class.getName());
        sb.append(" where exeId = '").append(id).append("'");
        dao.executeUpdate(sb.toString());
        // 删除执行记录
        dao.delete(BatchExecution.class, id);
    }

    @Override
    @Transactional
    public int updateStatusSuccess(String id) {
        StringBuilder sb = new StringBuilder();
        sb.append("update ").append(BatchExecution.class.getName()).append(" t");
        sb.append(" set t.status = ").append(3);
        sb.append(" where t.id = '").append(id).append("'");
        sb.append(" and t.addr = ");
        sb.append("(");
        sb.append("select concat('broadcast:',count(*)) from ").append(BatchEvent.class.getName()).append(" e");
        sb.append(" where e.exeId = '").append(id).append("'");
        sb.append(" and e.status = ").append(3);
        sb.append(")");
        this.dao.executeHql(sb.toString());
        return 0;
    }

    @Override
    @Transactional
    public int updateStatusFailed(String id) {
        StringBuilder sb = new StringBuilder();
        sb.append("update ").append(BatchExecution.class.getName()).append(" t");
        sb.append(" set t.status = ").append(4);
        sb.append(" where t.id = '").append(id).append("'");
        sb.append(" and t.addr = ");
        sb.append("(");
        sb.append("select concat('broadcast:',count(*)) from ").append(BatchEvent.class.getName()).append(" e");
        sb.append(" where e.exeId = '").append(id).append("'");
        sb.append(" and e.status in (3,4,7,8)");
        sb.append(")");
        this.dao.executeHql(sb.toString());
        return 0;
    }
}